#include <math.h>
#include <windows.h>
#include <stdio.h>

#include "config.h"
#include "event.h"
#include "util.h"
#include "obd_pid.h"

#define TWO_AXIS_DIFF_MIN 1000

/* what speed to count as a 'stop' */
#define MPH_STOP_SPEED 3
#define MPH_START_SPEED 5

int
main(int argc, char **argv)
{
	FILE *fpcfg, *fplog;
	char *cfg_file, *log_file;
	int r;
	struct config config;
	uint32_t next, file_size;
	int session_num;
	int cur_session;
	double time;
	int i, j;
	double min[NUM_LOG_SLOTS], max[NUM_LOG_SLOTS];
	int firstrun[NUM_LOG_SLOTS];
	char *out_file;
	char *in_file;
	int num_stops;
	int speed_state;
	int speed_present;
	double stopped_time;
	double distance;
		
	if (argc != 4) {
		fprintf(stderr, "usage: %s config_file log_file "
		    "session_num\n", argv[0]);
		exit(1);
	}

	cfg_file = argv[1];
	log_file = argv[2];
	session_num = atoi(argv[3]);

	fpcfg = fopen(cfg_file, "rb");
	if (fpcfg == NULL) {
		fprintf(stderr, "error: could not open %s\n", cfg_file);
		exit(1);
	}

	r = fread(&config, 1, sizeof(config), fpcfg);

	if (!valid_config(&config)) {
		fprintf(stderr, "error: invalid config read.\n");
		exit(1);
	}
	
	fplog = fopen(log_file, "rb");
	if (fplog == NULL) {
		fprintf(stderr, "error: could not open %s\n", log_file);
		exit(1);
	} 
	fseek(fplog, 0, SEEK_END);
	file_size = ftell(fplog);
	rewind(fplog);

	cur_session = 0;
	while (cur_session <= session_num) {
		r = fread(&next, 1, sizeof(next), fplog);
		if (r != sizeof(next)) {
			fprintf(stderr, "error: could not read next"
			    " address (session # too big)\n");
			exit(1);
		}

		if (cur_session == session_num)
			break;

		if (fseek(fplog, next, SEEK_SET) == -1) {
			fprintf(stderr, "error: could not seek next"
			    " address (session # too big)\n");
			exit(1);
		}

		++cur_session;
	}

	if (ftell(fplog) == file_size) {
		fprintf(stderr, "error: invalid session number\n");
		exit(1);
	}

	for (i = 0; i < NUM_LOG_SLOTS; ++i)
		firstrun[i] = 1;

#define MOVING 0
#define STOPPED 1

	time = 0;
	num_stops = 0;
	speed_state = STOPPED;
	speed_present = 0;
	stopped_time = 0;
	distance = 0;
	while (ftell(fplog) < next) {
		uint32_t data;
		double value;

		time += 0.5;

		for (i = 0; i < NUM_LOG_SLOTS; ++i) {
			if (config.event[i].interval == 0)
				continue;
			
			config.event[i].count++;

			if (config.event[i].count == config.event[i].interval) {
				config.event[i].count = 0;

				/* read the data, inc addr */
				data = 0;
				r = fread(&data, 1, PID_LENGTH(config.event[i].pid), fplog);
				if (r == 0) {
					fprintf(stderr, "error: read\n");
					exit(1);
				}

				if (PID_LENGTH(config.event[i].pid) == 2) {
					data = htons(data);
				} else if (PID_LENGTH(config.event[i].pid) == 4) {
					data = htonl(data);
				}

				value = conv_pid_data(config.event[i].pid, data);

				if (config.event[i].pid == VEHICLE_SPEED) {
					static double last_accel = 0;
					static double last_speed = -1;
					static double accel;

					speed_present = 1;
					if (speed_state == STOPPED) {
						stopped_time += 0.5;
						if (num_stops == 0)
							++num_stops;
					}

					if (value < MPH_STOP_SPEED &&
					    speed_state == MOVING) {
						speed_state = STOPPED;
						++num_stops;
#if 0
						printf("stop at time: %.02f\n", time);
#endif
					} else if (value > MPH_START_SPEED)
						speed_state = MOVING;
					
					distance += config.event[i].interval * 0.5 * value;

					if (last_speed == -1)
						last_speed = value;

					accel = (value - last_speed) / (config.event[i].interval * 0.5);
//accel					printf("%.02f %.02f\n", time, accel / 3600.0 * 1609.344);

					last_speed = value;
				}

				if (firstrun[i]) {
					min[i] = value;
					max[i] = value;
					firstrun[i] = 0;
				} else {
					if (min[i] > value)
						min[i] = value;
					if (max[i] < value)
						max[i] = value;
				}
			}
		}
	}

//	exit(0);
	
	for (i = 0; i < NUM_LOG_SLOTS; ++i) {
		if (config.event[i].interval == 0)
			continue;
		
		printf("%s:\n", pid_name[config.event[i].pid]);

		printf("\tMin: %.02f %s\n", min[i],
		    pid_units(config.event[i].pid));
		printf("\tMax: %.02f %s\n", max[i],
		    pid_units(config.event[i].pid));
		printf("\n");
	}

	if (speed_present) {
		printf("Number of stops: %d\n", num_stops);
		printf("Amount of time stopped: %02d:%02d:%02d (%.2f seconds)\n", (int) floor(stopped_time / 3600), (int) floor(stopped_time / 60), (int) stopped_time % 60, stopped_time);
		printf("Disntance travelled: %.02f miles\n", distance / 3600);
	}

	fclose(fpcfg);
	fclose(fplog);

	return 0;
}
